
#include <BScene>
#include "member_BScene.h"

using namespace BWE;

#define member					(*(member_BScene*)_ptr)
#define member_allocate()		_ptr = new member_BScene(this)
#define member_release()		delete (member_BScene*)_ptr

BScene::BScene()
{
	member_allocate();
}
BScene::~BScene()
{
	member_release();
}

void BScene::addNode(BNode* node)
{
	if (node && !member.nodes.contain(node))
	{
		if (BLight* light = dynamic_cast<BLight*>(node))
		{
			member.lights.append(light);
		}
		else if (BCamera* camera = dynamic_cast<BCamera*>(node))
		{
			member.cameras.append(camera);
		}
		else
		{
			member.nodes.append(node);
		}
		member.dirtySpace = true;
	}
}
void BScene::removeNode(BNode* node)
{
	if (node)
	{
		if (BLight* light = dynamic_cast<BLight*>(node))
		{
			member.lights.remove(light);
		}
		else if (BCamera* camera = dynamic_cast<BCamera*>(node))
		{
			member.cameras.remove(camera);
		}
		else
		{
			member.nodes.remove(node);
		}
		member.dirtySpace = true;
	}
}

bool BScene::contains(const BNode* node) const
{
	return member.nodes.contain(node);
}

int BScene::nodeCount() const
{
	return member.nodes.size();
}
BNode* BScene::node(int index)
{
	BNodeHolder node = member.nodes(index);
	return node.ptr();
}
const BNode* BScene::node(int index) const
{
	BNodeHolder node = member.nodes(index);
	return node.ptr();
}

BNode* BScene::node(const BString& name)
{
	for (int i = 0; i < member.nodes.size(); i++)
	{
		BNode* node = member.nodes[i];
		if (node->name() == name)
			return node;
	}
	return 0;
}
const BNode* BScene::node(const BString& name) const
{
	for (int i = 0; i < member.nodes.size(); i++)
	{
		BNode* node = member.nodes[i];
		if (node->name() == name)
			return node;
	}
	return 0;
}

int BScene::lightCount() const
{
	return member.lights.size();
}
BLight* BScene::light(int index)
{
	return member.lights(index);
}
const BLight* BScene::light(int index) const
{
	return member.lights(index);
}

int BScene::cameraCount() const
{
	return member.cameras.size();
}
BCamera* BScene::camera(int index)
{
	return member.cameras(index);
}
const BCamera* BScene::camera(int index) const
{
	return member.cameras(index);
}

void BScene::clearNodes()
{
	member.nodes.clear();
	member.dirtySpace = true;
}
void BScene::clearLights()
{
	member.lights.clear();
	member.dirtySpace = true;
}
void BScene::clearCameras()
{
	member.cameras.clear();
	member.dirtySpace = true;
}
void BScene::clear()
{
	member.nodes.clear();
	member.lights.clear();
	member.cameras.clear();
	member.dirtySpace = true;
}

const BSpace& BScene::space() const
{
	if (member.dirtySpace)
	{
		BSpace space(member.nodes.first()->space());
		for (int i = 0; i < member.nodes.size(); i++)
		{
			BNode* node = member.nodes[i];
			space.expand(node->space());
		}
		if (member.space != space)
		{
			member.space = space;
		}
		member.dirtySpace = true;
	}
	return member.space;
}
